/*LICENSE_BEGIN
 * ******************************************************************
 * Copyright 2006 by the Dainamite Robocup-Team at the
 * DAI-Labor, TU-Berlin (www.dai-labor.de)
 * 
 * Members of Dainamite are:
 * Holger Endert
 * Robert Wetzker
 * Thomas Karbe
 * Axel Heßler
 * Philippe Bütter
 * Felix Brossmann
 * 
 * Licensed under the GNU GPL (General Public License) Free Software 
 * License, Version 2. You may use this file only in compliance with 
 * the License. You may obtain a copy of the License at:
 * 
 * http://www.fsf.org/licensing/licenses/gpl.txt
 * ******************************************************************
LICENSE_END*/
package robocup.component.actions;

/**
 * Abstract super-type for all implemented action. Basically, an action is 
 * anything that can be executed by the agents, e.g. a dash or a turn-action,
 * or a speechact.<br>
 * Actions are executed by sending a string-representation with key-words
 * and parameters to the server. Therefore, this class defines the abstract
 * method <code>toString()</code>, which must be overridden by all extending
 * subclasses. These have to create the correct syntax for the actions as 
 * defined in the server manual, using the given values as parameter. Note
 * that some actions, which are introduced to the server after the release of 
 * the manual, are implemented as well, such as point-to and attention-to.
 * 
 */
public abstract class Action {

	/** 
	 * IDs for all possible action types. These can be used to check their type
	 * without making instanceof tests (for performance reasons). 
	 */
	public enum TYPE {
		DASH, MOVE, KICK, SAY, TURN, TURN_NECK, CATCH_BALL, CHANGE_VIEW_MODE, SENSE_BODY, TACKLE, POINTTO, ATTENTIONTO, COACH_EYE_MODE, COACH_PLAY_MODE, COACH_START, COACH_MOVE_PLAYER, COACH_MOVE_BALL, COACH_CHANGE_PLAYER_TYPE, COACH_RECOVER, COACH_LOOK, COACH_EAR_MODE, COACH_KILL_PLAYER;

		/**
		 * Checks, if this is a main-action, which is the case, if the action
		 * is one of DASH, MOVE, KICK, TURN, CATCH_BALL, SENSE_BODY or TACKLE.
		 * Main-actions are actions, which result in a movement and can be
		 * executed only exclusive Note that for instance turn-neck is not
		 * a main action, because it can be concurrently to main-actions.
		 * 
		 * @return true if the action is a main action
		 */
		public boolean isMain() {
			switch (this) {
			case DASH:
			case MOVE:
			case KICK:
			case TURN:
			case CATCH_BALL:
			case SENSE_BODY:
			case TACKLE:
				return true;
			default:
				return false;
			}
		}
	};

	/**
	 * double parameters are rounded to this many decimal places
	 */
	static protected final int PARAMETER_PRECISION = 3;

	/**
	 * The type of the action.
	 */
	protected TYPE _type;

	/**
	 * Default-constructor of the Action-class.
	 */
	public Action() {
	}

	/**
	 * Getter for the action-type, which corresponds always to the sub-class, 
	 * i.e the DashAction is always of type TYPE.DASH.
	 * 
	 * @return the type of this class.
	 */
	public TYPE getType() {
		return this._type;
	}

	/**
	 * An action is worth sending if it effects the world.
	 * 
	 *  @return true, if the action has an impact on the world. This is for 
	 *  instance not the case for turn actions with turn-angle 0. 
	 */
	public boolean isWorthSending() {
		return true;
	}

	/**
	 * This definition enforces all extending classes to implement a toString
	 * method (which is here set to abstract), such that their string-
	 * representation can be sent to the server as command.
	 * 
	 * @return string - the string-representation of this action in valid 
	 * syntax.
	 */
	@Override
	public abstract String toString();
}
